package cn.tjie.basic.service.impl;

import cn.tjie.basic.dto.CodeDto;
import cn.tjie.basic.exception.BusinessException;
import cn.tjie.basic.service.IVerifyCodeService;
import cn.tjie.basic.util.SmsUtils;
import cn.tjie.basic.util.StrUtils;
import cn.tjie.basic.util.VerifyCodeUtils;
import cn.tjie.user.domain.User;
import cn.tjie.user.mapper.UserMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;
    @Override
    public String getImageCode(String key) {
        //1.获取图形验证码

        String code = StrUtils.getComplexRandomString(4);
        //2 保存到redis
        redisTemplate.opsForValue().set(key,code,5, TimeUnit.MINUTES);

        //3.将图形验证码写入图片编码成base64位的字符串
        return VerifyCodeUtils.verifyCode(115, 40, code);

    }

    @Override
    public void phoneVerifyCode(CodeDto codeDto) {
        String phone = codeDto.getPhone();
        String inputImageCode = codeDto.getImageCode();
        String key = codeDto.getImageCodeKey();
        //一：校验：空值校验 - 前端和后端都可以校验手机格式问题
        if(StringUtils.isEmpty(phone)||StringUtils.isEmpty(inputImageCode)) {
         throw new BusinessException("信息不能为空！！！");
        }
        //二：校验：手机号码是否注册过
        User user = userMapper.findByPhone(phone);
        if(user!=null) {
            throw new BusinessException("手机号已被注册，请直接登录！！！");
        }
        //三：校验：图形验证码 - 是否过期，是否正确
        //1.根据前端传递的ImageCodeKey获取到存到redis的图形验证码，转成字符串，并且全部小写
        String redisImageCode = redisTemplate.opsForValue().get(key).toString().toLowerCase();
        if(redisImageCode==null) {
            throw new BusinessException("图形验证码已过期！！！");
        }
        //2.把redisImageCode跟前端用户输入的inputImageCode的做对比
        if(!inputImageCode.trim().toLowerCase().equals(redisImageCode)) {
            throw new BusinessException("图形验证码错误！！！");
        }
//四：直接从redis获取手机验证码：key【业务🗡:手机号】
        Object phoneCode = redisTemplate.opsForValue().get("register:" + phone);
        //redis里面有手机验证码，且用户在一分钟之类重复点击
        if(phoneCode!=null) {
            //2.获取到了 = 没有过期，判断重发时间【时间戳 】
            Long oldTime = Long.parseLong(phoneCode.toString().split(":")[1]);
            if(System.currentTimeMillis()-oldTime<60*1000) {
                //a.如果没有过重发时间 - 没有重发时间，居然发请求过了 = 违规操作 - 抛异
                throw new BusinessException("请勿频繁操作！！！");
            }
        }
        //redis里面没有手机验证码或者过了重发时间，获取新的验证码 【code:时间戳】
        String code = StrUtils.getRandomString(4);

        //五：将key和验证码保存在redis，重新设置过期时间3分钟【如果是用以前的-这句话就刷新了过期时间】
        redisTemplate.opsForValue().set("register:" + phone,code+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);
        //六：调用短信的工具类发送短信
        SmsUtils.sendSms(phone,"你的手机验证码是：" + "5201314" +",你是瓜娃子,哈哈哈哈!!!");
        System.out.println("你的手机验证码是：" + "code" +",请在3分钟内使用!!!");
    }

    @Override
    public void binderSmsCode(CodeDto codeDto) {
        String phone = codeDto.getPhone();
        //一：校验：空值校验 - 前端和后端都可以校验手机格式问题
        if(StringUtils.isEmpty(phone)){
            throw new BusinessException("电话不能为空！！！");
        }
//四：直接从redis获取手机验证码：key【业务🗡:手机号】
        Object phoneCode = redisTemplate.opsForValue().get("binder:" + phone);
        //redis里面有手机验证码，且用户在一分钟之类重复点击
        if(phoneCode!=null) {
            //2.获取到了 = 没有过期，判断重发时间【时间戳 】
            Long oldTime = Long.parseLong(phoneCode.toString().split(":")[1]);
            if(System.currentTimeMillis()-oldTime<60*1000) {
                //a.如果没有过重发时间 - 没有重发时间，居然发请求过了 = 违规操作 - 抛异
                throw new BusinessException("请勿频繁操作！！！");
            }
        }
        //redis里面没有手机验证码或者过了重发时间，获取新的验证码 【code:时间戳】
        String code = StrUtils.getRandomString(4);

        //五：将key和验证码保存在redis，重新设置过期时间3分钟【如果是用以前的-这句话就刷新了过期时间】
        redisTemplate.opsForValue().set("binder:" + phone,code+":"+System.currentTimeMillis(),3,TimeUnit.MINUTES);
        //六：调用短信的工具类发送短信
        //SmsUtils.sendSms(phone,"你的手机验证码是：" + "5201314" +",请在3分钟内使用!!!");
        System.out.println("你的手机验证码是：" + code +",请在3分钟内使用!!!");
    }
}
